(function()
{
	var appFun = function()
	{
		var that = this;
		this.core = 'core1';
		if (window.config && config.core)
			this.core = config.core;
		this.servers = {};
		// 当前模板列表
		this.templeteList = {};
		this.lastRefreshToken = getTime();
		// 本地存储的缓存
		this.storage = {};
		// 设置固定值
		this.fixedStorageKeyValue = {};
		this._business = {
			id : 0
		};
		this._businessSingle = null;
		// 是否处于展板模式，处于展板模式将会减少一些功能
		this.isBoard = false;
		// PC 模式
		this.PcModel = false;
		this.bottomlayerIndex = 0;
		// 手机模式，可能会减少功能
		this.m = null;
		// 手机视图，但可能需要显示更多数据，只是为了显示，不减少功能
		this.vm = ($(window).width() < 600);
		if (!config.langlist)
		{
			config.langlist = {
				zh : '中文'
			}
		}
		if (config.debug)
			config.langlist['none'] = 'None';
		// 后台自动任务
		this.runTimer();
		setInterval(function()
		{
			if (!that.haveInit)
				return;
			that.runTimer();
		}, this.getInterval());
	};
	/**
	 * 取得间隔时间
	 */
	appFun.prototype.getInterval = function()
	{
		return 60000; // 1分钟
	}
	appFun.prototype.runTimer = function(key, fun)
	{
		if (!this.runTimer.list)
		{
			this.runTimer.list = {};
			this.runTimer.keys = [];
			this.runTimer.rkeys = [];
			this.runTimer(1, function()
			{
				loginWorktask.readTasktypeNew(true);
			});
			this.runTimer(2, function()
			{
				loginWorksheet.haveNew();
			});
			this.runTimer(3, function()
			{
				ajax.clearCache();
			});
			this.runTimer(4, function()
			{
				loginBacktask.runAutoTask(true);
			});
			this.runTimer(5, function()
			{
				left.showLogoFace();
			});
		}
		if (key)
		{
			if (fun)
			{
				if (!this.runTimer.list[key])
					this.runTimer.keys.push(key);
				this.runTimer.list[key] = fun;
			}
			else if (this.runTimer.list[key])
			{
				delete this.runTimer.list[key];
				var i = this.runTimer.keys.indexOf(key);
				if (i >= 0)
					this.runTimer.keys.splice(i, 1);
			}
		}
		if (!window.left || !left.showWrapper() || this.isSinglePage())
			return;
		var timerMs = this.getInterval();
		var n = this.runTimer.keys.length + 1;
		if (n <= 1)
			return;
		for (var i = 0; i < this.runTimer.keys.length; i++)
		{
			this.runTimer.rkeys.push(this.runTimer.keys[i]);
			var that = this;
			setTimeout(function()
			{
				var key = that.runTimer.rkeys.shift();
				if (key && that.runTimer.list[key])
					that.runTimer.list[key]();
			}, timerMs * (i + 1) / n);
		}
	}
	/**
	 * 设定锁定屏幕时间，当ms为0时不设定 unlockFun 为解锁时执行的程序 返回是否被锁定
	 */
	appFun.prototype.lockScreen = function(ms, unlockFun)
	{
		var now = new Date().getTime();
		if (ms > 0)
			this.lockScreen.time = now + ms;
		if (unlockFun)
		{
			if (!this.lockScreen.time || this.lockScreen.time <= now)
				unlockFun();
			else
			{
				var that = this;
				setTimeout(function()
				{
					that.lockScreen(0, unlockFun);
				}, this.lockScreen.time - now);
			}
		}
		return this.lockScreen.time > now;
	}
	/**
	 * 单页面
	 */
	appFun.prototype.isSinglePage = function(set)
	{
		if (set !== undefined && set !== null)
			this.isSinglePage.v = !!set;
		return this.isSinglePage.v;
	}
	/**
	 * 调入标签
	 */
	appFun.prototype.showNote = function(close, isinit, backfun, toMin)
	{
		var timeout = 1000 * 3600 * 24 * 7;
		var stKey = 'haveNotes';
		var isset = false;
		if (toMin === true || toMin === 1)
		{
			return this.setStorage(stKey, 'min');
		}
		else if (toMin === false || toMin === 0)
		{
			return this.setStorage(stKey, 'yes');
		}
		if (!login.haveAuth('login', 'W'))
		{
			// 只对员工开放标签
			close = true;
		}
		else
		{
			var first = this.haveNote === undefined;
			if ((close === undefined || close === null) && isinit)
			{
				if (this.haveNote === undefined || isinit)
				{
					var v = this.getStorage(stKey, false, timeout);
					close = v != 'yes' && v != 'min';
					if (v == 'min')
					{
						var t = parseInt(v.substring(3));
						if (t > 0 && t < getTime() - 3600 * 24 * 3)
							close = true;
					}
				}
				else
					close = !!this.haveNote;
			}
			else
				isset = true;
			this.haveNote = !close;
			if (isset)
			{
				if (this.haveNote)
				{
					if (this.getStorage(stKey) != 'min')
						this.setStorage(stKey, 'yes');
				}
				else
					this.setStorage(stKey, 'no');
			}
		}
		// /////////////////////////////
		if (close)
		{
			$('aside.main-sidebar .sidebar #roottree').show();
			$('aside.main-sidebar .sidebar .user-panel').show();
			$('aside.main-sidebar .sidebar .notes').remove();
			$('.main-sidebar').css('box-shadow', '2px 0px 2px #888888');
			$('.wrapper').removeClass('min-notes');
			left.bodyLeftMenu(true, null, false);
			if (window.loginNote)
				loginNote.openLeft(true);
			if (backfun)
				backfun();
		}
		else
		{
			if (this.getStorage(stKey) == 'min')
				$('.wrapper').addClass('min-notes');
			$('aside.main-sidebar .sidebar #roottree').hide();
			$('aside.main-sidebar .sidebar .user-panel').hide();
			$('aside.main-sidebar .sidebar .notes').remove();
			$('.main-sidebar').css('box-shadow', '0px 0px 0px #888888');
			$('aside.main-sidebar .sidebar').append("<div class='notes' id='notes'><div class='note' id='note'></div></div>");
			loadJs('servers/login/note.js', function()
			{
				loginNote.list();
				setTimeout(function()
				{
					var k = $('aside.main-sidebar .sidebar #notes #note');
					if (k.length <= 0)
						return;
					var odd = getOffset(k[0]);
					var minh = $(window).height() - odd.top;
					$('aside.main-sidebar .sidebar #notes #note').css('height', minh + 'px');
					if (backfun)
						backfun();
					left.bodyLeftMenu(true, null, true);
				}, first ? 3000 : 100);
			});
		}
		left.rightTopMenu(true);
	}
	/**
	 * 取得当前商家还是所有商家的编号，所有商家返回
	 */
	appFun.prototype.allBusinessOrCurBusiness = function(justName, curBusinessId, returnValue)
	{
		var that = this;
		var setToAll;
		if (returnValue == 1 || returnValue === false)
			setToAll = false;
		else if (returnValue == -1 || returnValue === true)
			setToAll = true;
		else if (returnValue == -2)
		{
			var oldBid = this._business.id;
			this.selectBusiness(function(businessId)
			{
				if (oldBid != that._business.id)
					that.allBusinessOrCurBusiness(0, 0, false);
				else
				{
					$('.cmdbox .curb.rightmenu span.cap').html(that.allBusinessOrCurBusiness.isAll ? that.w('allBusiness') : that.w('curBusiness'));
				}
			}, true);
			return false;
		}
		var isSingleBusiness = this.isSingleBusiness();
		if (justName === undefined)
		{
			var r = {
				'1' : this.w('curBusiness') + '(' + this.getBusinessName() + ')'
			};
			if (!isSingleBusiness)
			{
				r['-1'] = this.w('allBusiness');
				r['-2'] = this.w('selectOtherBusiness');
			}
			return r;
		}
		if (isSingleBusiness)
		{
			curBusinessId = this._business.id;
			isAll = false;
		}
		else
		{
			if ((curBusinessId != this._business.id) || !(curBusinessId > 0))
				curBusinessId = 0;
			if (this.allBusinessOrCurBusiness.isAll === undefined)
			{
				this.allBusinessOrCurBusiness.isAll = this.getStorage('isAllBusiness') == 'yes';
			}
			var isAll = this.allBusinessOrCurBusiness.isAll;
			if (setToAll === true || setToAll === false)
			{
				isAll = setToAll;
				this.setStorage('isAllBusiness', isAll ? 'yes' : 'no');
				if (curBusinessId > 0)
					isAll = false;
				if (!isAll && !(this._business.id > 0))
					isAll = true;
				this.allBusinessOrCurBusiness.isAll = isAll;
			}
		}
		if (isAll)
			return justName ? this.w('allBusiness') : -1;
		else
			return justName ? this.w('curBusiness') : this._business.id;
	}
	appFun.prototype.changeJob = function(jobs)
	{
		var that = this;
		if (!jobs)
		{
			ajax.request('wtp.login.jobs.myJobList', {}, function(d, ad)
			{
				var jobs = [];
				for (var i = 0; i < d.length; i++)
				{
					jobs.push(d[i]);
				}
				if (jobs.length <= 0)
					errorMsg('no jobs');
				else
					that.changeJob(jobs);
			});
			return;
		}
		var a = {};
		for (var i = 0; i < jobs.length; i++)
		{
			a[jobs[i].id] = jobs[i].name + (jobs[i].cur ? '<i class="fa fa-check"></i>' : '');
		}
		if (!left.okToChangeMain())
		{
			left.okToChangeMain(function()
			{
				that.changeJob(backfun, jobs);
			});
			return;
		}
		selectList(this.w('select'), a, function(jobsId)
		{
			if (jobsId > 0)
			{
				ajax.request('wtp.login.jobs.changeJob', {
					jobsId : jobsId
				}, function(d, ad)
				{
					loginUser.initPage(true);
				});
			}
		});
	}
	/**
	 * 读取或保存当前商家
	 */
	appFun.prototype.business = function(b)
	{
		if (arguments.length <= 0)
		{
			if (!this._business || !this._business.id)
			{
				this._business = this.getStorage('business');
				if (!this._business || !this._business.id)
				{
					this.business(null);
				}
				else if (this._business.id != login.getBusinessId())
				{
					this.business(null);
				}
			}
		}
		else if (arguments.length > 0)
		{
			if (!b || !(b.id > 0))
			{
				b = {
					id : 0,
					name : '',
				};
			}
			this._business = b;
		}
		this.setStorage('business', this._business && this._business.id > 0 ? this._business : '');
		var na = this._business.id <= 0 ? this.w('selectBusiness') : this.getBusinessName(true);
		$('.main-header #business').html(na);
		$('.bottommenu ul.m2 li span').html(na);
	}
	/**
	 * 注册模板（table、tab、form等）
	 */
	appFun.prototype.templete = function(ta)
	{
		if (ta)
		{
			if (typeof ta == 'string')
			{
				if (this.templeteList[ta])
					return this.templeteList[ta];
			}
			else
			{
				if (ta.id)
				{
					var tt = getTime();
					for ( var id in this.templeteList)
					{
						if ($('#' + id).length <= 0 && this.templeteList[id] && tt - this.templeteList[id].created > 5)
						{
							delete this.templeteList[id];
						}
					}
					ta.created = tt;
					this.templeteList[ta.id] = ta;
				}
			}
		}
		return null;
	}
	appFun.prototype.sendSound = function(address, message, backfun)
	{
		var that = this;
		ajax.request('wtp.login.mail.sendSound', {
			address : address,
			message : message,
		}, function(d, ad)
		{
			if (backfun)
				backfun();
		});
	}
	appFun.prototype.getOtherUrl = function()
	{
		if (this.getOtherUrl.value === '' || this.getOtherUrl.value)
			return this.getOtherUrl.value;
		var url = this.getHrefHost();
		var value = '';
		if (url.indexOf('testware.') > 0)
			value = url.replace('testware.', 'testadmin.');
		else if (url.indexOf('ware.admin') > 0)
			value = url.replace('ware.admin', 'www.admin');
		else if (url.indexOf('ware.') > 0)
			value = url.replace('ware.', 'admin.');
		else if (url.indexOf('testadmin.') > 0)
			value = url.replace('testadmin.', 'testware.');
		else if (url.indexOf('www.admin') > 0)
			value = url.replace('www.admin', 'ware.admin');
		else if (url.indexOf('admin.') > 0)
			value = url.replace('admin.', 'ware.');
		this.getOtherUrl.value = value;
		return value;
	}
	appFun.prototype.getHrefHost = function()
	{
		var url = window.location.href;
		var i = url.indexOf('?');
		if (i < 0)
			i = url.indexOf('#');
		if (i > 0)
			url = url.substring(0, i);
		return url;
	}
	/**
	 * 设置主输入框
	 */
	appFun.prototype.setMainInputObj = function(mainInputObjId, mainInputSubmitFun)
	{
		if (!this.mainInput)
			this.mainInput = [];
		if (mainInputObjId)
		{
			if (this.mainInputObjId)
			{
				this.mainInput.push({
					id : this.mainInputObjId,
					fun : this.mainInputSubmitFun
				});
			}
			this.mainInputObjId = mainInputObjId;
			this.mainInputSubmitFun = mainInputSubmitFun;
		}
		else
		{
			if (this.mainInput.length > 0)
			{
				var p = this.mainInput.pop();
				this.mainInputObjId = p.id;
				this.mainInputSubmitFun = p.fun;
				if ($('#' + this.mainInputObjId).length <= 0)
				{
					this.setMainInputObj();
				}
			}
			else
			{
				this.mainInputObjId = '';
				this.mainInputSubmitFun = null;
			}
		}
	}
	/**
	 * 设置程序界面大小
	 */
	appFun.prototype.setAppSize = function(must)
	{
		var that = this;
		var ww = $(window).width();
		var wh = $(window).height();
		if (this.setAppSize.timer)
		{
			clearTimeout(this.setAppSize.timer);
			this.setAppSize.timer = 0;
		}
		var oldvm = this.vm;
		var vm = ww < 600;
		if (this.vm != vm)
		{
			this.reload();
			this.vm = vm;
		}
		this.m = (this.vm && !this.PcModel);
		if (!this.vm)
			$('.main-header .navbar-custom-menu').hide();
		if (this.vm && this.PcModel)
			$('body').addClass('pcmodel');
		else
			$('body').removeClass('pcmodel');
		var topHeadNav = left.isTopHeadNav();
		var jqth = $('.top-header');
		var jqbh = $('.bottom-header');
		if (topHeadNav)
		{
			jqth.show();
			var jqst = $('.main-header .navbar-static-top');
			var jqme = $('.main-header .navbar-custom-menu');
			var lw = jqth.offset().left - jqst.offset().left;
			if (!lw && !must)
			{
				jqth.width(100);
				this.setAppSize.timer = setTimeout(function()
				{
					that.setAppSize(true)
				}, 333);
				return;
			}
			var w = jqst.width();
			var rw = jqme.width();
			jqth.width(w - lw - rw - 32);
			jqbh.hide();
		}
		else
		{
			jqth.hide();
			jqbh.show();
		}
		left.showNavBar();
		if (oldvm != this.vm && !this.vm && window.left)
			left.jp();
		var isp = this.getStorage('PcModel');
		if (isp)
		{
			this.PcModel = isp == 'yes';
			this.setStorage('PcModel', '');
		}
		this.m = (this.vm && !this.PcModel);
		if (!this.vm && left.isShowFace())
		{
			var pl = (ww - 1160) / 2;
			var st = Math.min(pl + 760, ww - 566);
			$('.mainface .title').css('left', st + 'px');
			$('.mainface').css('top', ((wh - 600) / 2) + 'px');
			var t = (ww + st) / 2 + 130;
			$('.mainface .wx_login_box').css('left', t + 'px');
			$('.mainface .wx_login_box').css('top', Math.max(0 - (wh - 600) / 2, -80) + 'px');
		}
		$('header.main-header .minlogo').css('display', '');
		$('div.user-panel .logo').css('display', '');
		if (this.vm)
		{
			if (this.PcModel)
			{
				$('header.main-header .minlogo').hide();
				$('header.main-header .toleft').hide();
				$('section.content-header').addClass('PcModel');
			}
			else
			{
				$('header.main-header .minlogo').show();
				$('header.main-header .toleft').show();
				$('section.content-header').removeClass('PcModel');
			}
		}
		var t = 0;
		$('.content-header').css('padding-top', t + 'px');
		if (oldvm != this.vm)
		{
			this.needWTPJp(config.needWTPJp && (this.vm || window.toAndroidApp));
			left.showBottom(this.vm);
		}
		var h = this.getMainHeight() - 6;
		$('#maincontent>div').css('min-height', h + 'px');
		if (!this.vm)
		{
			$('.main-header .navbar-custom-menu').show();
			resizeFullLayer(null, 333);
		}
		// 遍历所有 table
		table = (new tableFun);
		$('.tablebox .tophtml').each(function()
		{
			var ta = table.getThis(this);
			if (ta.cmdhtml)
				ta.cmdhtml.showMoreLeft();
		});
		if (window.toAndroidApp && window.toAndroidApp.setToPadModel)
		{
			if (ww > wh)
				window.toAndroidApp.setToPadModel('yes');
			else
				window.toAndroidApp.setToPadModel('no');
		}
		if (ww > 1000 && $('#headertopback').length <= 0 && !app.isSinglePage())
		{
			$('body .wrapper').prepend('<div style="display:none" id="headertopback"></div>');
		}
	}
	/**
	 * 取得空白位置
	 */
	appFun.prototype.getFullLayerPaddingY = function()
	{
		return app.vm ? 82 : 102;
	}
	/**
	 * 改变语言
	 */
	appFun.prototype.changeLang = function(lang)
	{
		this.setStorage('lang', lang);
		this.reload();
	}
	/**
	 * 取得当前服务的设置数据， serverName为空时把configPara.js中的配置合并过来（如果config.js原先存在某服务），由config.js设置加上configPara.js中的配置，都存在时以config.js优先。 serverName不为空时反回当前服务
	 */
	appFun.prototype.getServer = function(serverName)
	{
		if (serverName)
			return config.serversListConfig[serverName];
		else
		{
			var url = '';
			if (config.serversListConfig['login'] && config.serversListConfig['login']['url'])
				url = config.serversListConfig['login']['url'];
			for (serverName in config.serversListConfig)
			{
				var re = configPara.val('servers', serverName);
				if (config.serversListConfig[serverName] && re)
				{
					for ( var k in re)
					{
						if (config.serversListConfig[serverName][k] === undefined)
							config.serversListConfig[serverName][k] = re[k];
					}
					if (!config.serversListConfig[serverName]['url'])
						config.serversListConfig[serverName]['url'] = url;
				}
			}
		}
		return {};
	}
	/**
	 * 初始化对象，主要是用于加载微服务，一般权限更改、商家更改均要运行
	 */
	appFun.prototype.init = function(must, notNeedloadServer)
	{
		var that = this;
		if (this.init.isRun && !must)
			return;
		if (!this.init.isRun)
			this._doInit();
		this.init.isRun = true;
		var wxid = this.getStorage('loginByWxid', true, 20000);
		if (wxid)
		{
			if (!window.login)
			{
				if (notNeedloadServer)
					return;
				that.loadServer(function()
				{
					that.init(true, true);
				});
				return;
			}
			this.setStorage('loginByWxid', '');
			var i = wxid.indexOf(':js:');
			if (i > 0)
			{
				var js = (new Base64()).decode(wxid.substring(i + 4));
				loginUser.initPage(function()
				{
					eval(js);
				});
				wxid = wxid.substring(0, i);
			}
			this.init.isRun = false;
			login.loginByWxid(wxid, function()
			{
				that.init(true);
			});
			return;
		}
		else
		{
			var href = window.location.href;
			var key = '_wxid_';
			var i = href.indexOf(key);
			if (i < 0)
			{
				key = '?wxid';
				i = href.indexOf(key);
			}
			if (i >= 0)
			{
				var v = href.substring(i + key.length);
				this.setStorage('loginByWxid', v);
				var herf2 = window.location.href.substring(0, i);
				window.location.href = herf2;
				if (herf2.indexOf('#') > 0)
					this.init(true);
				return;
			}
		}
		this.servers = {};
		this.setLang(this.getLangName(), function()
		{
			that.loadServer(function()
			{
				that.readVersion(false, function()
				{
					that.haveInit = true;
					left.changeFace();
					left.setLogo();
					left.setWrapperHeight();
					that.bodyMax();
					that.setAppSize();
					left.bodyLeftMenu(true);
					left.rightTopMenu();
					left.showBottom(true);
					if (login.isLogin())
						loginUser.initPage();
					else
						that.setHome();
				});
			});
		});
	};
	appFun.prototype._doInit = function()
	{
		app.setFixedStorageKeyValue({
			'bodyLeftMenu' : 'no',
			'bodyMax' : 'yes',
			'lang' : 'zh'
		});
	}
	/**
	 * 取得网址 ， 以斜线结尾
	 */
	appFun.prototype.getWindowHref = function()
	{
		var url = window.location.href;
		var i = window.location.href.indexOf('#');
		if (window.location.href.indexOf('?') > 0)
			i = window.location.href.indexOf('?');
		if (i > 0)
			url = url.substring(0, i);
		url = url.replace('index.html', '');
		if (url.substring(url.length - 1, url.length) != '/')
			url += '/';
		return url;
	}
	/**
	 * 重载网页
	 */
	appFun.prototype.reload = function(path)
	{
		var that = this;
		if (!left.okToChangeMain())
		{
			left.okToChangeMain(function()
			{
				that.reload(path);
			});
			return;
		}
		if (path === undefined)
			path = app.hash();
		var businessId = this.getHrefPara('businessId', true);
		var url = this.getWindowHref() + '?r=' + Math.floor(Math.random() * 1000);
		if (businessId > 0)
			url += '&businessId=' + businessId;
		url += (path ? ('#_' + path) : '');
		url = url.replace('.html/', '.html');
		layer.msg('loading ...');
		window.location.href = url;
	}
	/**
	 * 取得当前语言
	 */
	appFun.prototype.getLangName = function()
	{
		var lang = this.getStorage('lang');
		if (!lang)
			lang = config.defaultLang;
		// if (!lang)
		lang = 'zh';
		return lang;
	}
	/**
	 * 取得程序版本号
	 */
	appFun.prototype.readVersion = function(forceRefresh, backfun, notHint, notSure, skin)
	{
		var that = this;
		if (forceRefresh && !left.okToChangeMain())
		{
			left.okToChangeMain(function()
			{
				that.readVersion(forceRefresh, backfun, notHint, notSure, skin);
			});
			return;
		}
		var failedFun = function(msg, msg2)
		{
			errorMsg(msg2);
			if (backfun)
				backfun();
		}
		if (forceRefresh)
		{
			if (!notSure)
			{
				var skinlist = configPara.val('skinlist');
				if (login.haveAuth('login', 'U'))
				{
					var arr = {};
					for ( var k in skinlist)
						arr[k] = skinlist[k];
					selectList(this.w('changeFace'), arr, function(skin)
					{
						that.readVersion(forceRefresh, backfun, notHint, true, skin, true);
					}, '', null, false, true);
				}
				else
				{
					confirm(this.w('login.msg.forceRefresh'), function()
					{
						that.readVersion(forceRefresh, backfun, notHint, true, skin, true);
					});
				}
				return;
			}
			if (!skin)
			{
				skin = this.getSkin() + ',' + this.getSkin(true);
			}
			ajax.request('wtp.login.tools.readVersion', {
				refresh : 'yes',
				skin : skin ? skin : '',
				core : this.core,
				adminDir : config.wtpAdminDir,
			}, function(d, ad)
			{
				that.reload();
				if (notHint)
				{
					if (backfun)
						backfun()
				}
				else
				{
					showMsg('', that.w('optionOk'), 0, backfun);
				}
			}, failedFun);
		}
		else
		{
			if (this.isSinglePage())
			{
				if (backfun)
					backfun();
				return;
			}
			ajax.request('wtp.login.tools.readVersion', {
				core : this.core,
				adminDir : config.wtpAdminDir,
			}, function(d, ad)
			{
				var version = getCurVersion(true, ad['version']);
				var debug = (ad['debug'] + ' ').trim().toLowerCase();
				debug = (debug == '1' || debug == 'true' || debug == 'yes');
				if (config.debug != debug)
				{
					config.debug = debug;
				}
				var curVersion = getCurVersion(true);
				if (version != curVersion)
				{
					loginUser.initPage(function()
					{
						var s = '<p>curVersion is ' + curVersion;
						s += '<p>newVersion is ' + version;
						if (!that.haveReloadVersion())
						{
							that.haveReloadVersion(true);
							confirm(that.w('login.msg.updateVersion') + '?<p>&nbsp;<p>' + s, function()
							{
								that.reload();
							});
						}
					});
				}
				if (backfun)
					backfun();
			}, failedFun, true, true);
		}
	}
	appFun.prototype.haveReloadVersion = function(read)
	{
		var vv = Math.floor(getTime() / (3600 * 12));
		if (read)
		{
			this.setStorage('haveReloadVersion', vv);
			return read;
		}
		else
		{
			return (vv == this.getStorage('haveReloadVersion'));
		}
	}
	/**
	 * 取得锚的参数值
	 */
	appFun.prototype.getHrefPara = function(key, isInt)
	{
		var reg = new RegExp('(^|&)' + key + '=([^&]*)(&|$)', 'i');
		var r = window.location.search.substr(1).match(reg);
		var re = isInt ? 0 : '';
		if (r && r[2])
		{
			if (isInt)
			{
				re = parseInt(r[2]);
				if (!re)
					re = 0;
			}
			else
			{
				re = r[2];
			}
		}
		return re;
	}
	/**
	 * 播放音效 delay > 0 表示读完后再读下一个，且再加间隔 delay 时间(ms) afterfun 播放完后执行这个
	 */
	appFun.prototype.play = function(name, delay, afterfun)
	{
		return music.play(name, delay, afterfun);
	}
	/**
	 * 根据设置看能不能显示某服务
	 */
	appFun.prototype.isShowServer = function(serverName)
	{
		if (serverName == 'login')
			return true;
		var isshow = true;
		// 根据设置
		if (this._isHiddenServerByConf(serverName) || (config.serversListConfig[serverName] && config.serversListConfig[serverName].hidden))
		{
			isshow = false;
			if (config.serversListConfig[serverName])
				config.serversListConfig[serverName].isHiddenByConf = true;
		}
		// 根据权限
		else if (this._isHiddenServerByAuth(serverName))
		{
			isshow = false;
		}
		return isshow;
	}
	/**
	 * 根据权限看能不能加载模块
	 */
	appFun.prototype._isHiddenServerByAuth = function(serverName)
	{
		if (serverName == 'login')
			return false;
		if (this._business.id <= 0)
			return true;
		var auth = this.getStorage('userauth');
		var reg = new RegExp(',' + serverName + '.[A-Z1-9]{0,34}Z[A-Z1-9]{0,34},');
		var isshow = reg.test(',' + auth + ',');
		return !isshow;
	}
	appFun.prototype.getSkin = function(color)
	{
		if (color)
		{
			var color = (typeof cur_color == 'string' ? cur_color : '');
			return color || 'blue';
		}
		var skin = (typeof cur_skin == 'string' ? cur_skin : '');
		return skin || 'default';
	}
	/**
	 * 加载微服务模块，sc为要加载的模块，sc==true表示结束了
	 */
	appFun.prototype.loadServer = function(backfun, sc, afterMs)
	{
		var that = this;
		if (that.loadServer.timer > 0)
		{
			clearTimeout(that.loadServer.timer);
			that.loadServer.timer = 0;
		}
		if (afterMs > 0)
		{
			that.loadServer.timer = setTimeout(function()
			{
				that.loadServer.timer = 0;
				that.loadServer(backfun, sc);
			}, afterMs);
			return;
		}
		if (typeof sc == 'object')
		{
			if (sc && sc.length > 0)
			{
				var sci = sc.shift();
				var serverName = sci.name;
				if (serverName)
				{
					var url = sci['url'];
					that.servers[serverName] = {
						lang : that.lan ? that.lan.lang : 'none',
						url : url,
					};
					if (that.lan && that.lan.lang != 'none' && serverName != 'login')
					{
						// 有语言包先调语言包
						that.loadLang(serverName, function()
						{
							loadJs('servers/' + serverName + '/index.js', function()
							{
								that.loadServer(backfun, sc);
							});
						});
					}
					else
					{
						loadJs('servers/' + serverName + '/index.js', function()
						{
							that.loadServer(backfun, sc);
						});
					}
				}
			}
			return;
		}
		else
		{
			loadJs(function()
			{
				left.init();
				for ( var serverName in that.servers)
				{
					if (window[serverName])
					{
						eval(serverName + '.start()');
					}
				}
				if (backfun)
				{
					backfun();
				}
			});
		}
		sc = [];
		var haveset = {};
		that.servers = {};
		// 先排要求顺序的
		var stort = this.getShowHostListByConfig().split(',');
		for (var is = 0; is < stort.length; is++)
		{
			stort[is] = stort[is].trim();
			for ( var name in config.serversListConfig)
			{
				if (haveset[name] || stort[is] != name || name == 'login')
					continue;
				if (this.isShowServer(name))
				{
					var s = config.serversListConfig[name];
					s['name'] = name;
					sc.push(s);
					haveset[name] = true;
				}
				break;
			}
		}
		// 最后追加login
		var s = config.serversListConfig['login'];
		if (s)
		{
			s['name'] = 'login';
			sc.push(s);
			haveset['login'] = true;
		}
		this.loadServer(backfun, sc);
	}
	/**
	 * 调入语言包
	 */
	appFun.prototype.loadLang = function(serverName, backfun)
	{
		var that = this;
		loadJs('lang/servers/' + serverName + '/' + that.lan.lang + '.js', function()
		{
			if (backfun)
				backfun();
		});
	}
	appFun.prototype.loadJsFile = function(serverName, filename, backfun)
	{
		var that = this;
		ajax.loading(10000);
		this.loadLang(serverName, function()
		{
			if (!filename)
			{
				loadJs('servers/' + serverName + '/index.js', function()
				{
					ajax.loading();
					if (backfun)
						backfun();
				});
			}
			else
			{
				loadJs('servers/' + serverName + '/index.js', function()
				{
					loadJs('servers/' + serverName + '/' + filename + '.js', function()
					{
						ajax.loading();
						if (backfun)
							backfun();
					});
				});
			}
		});
	}
	appFun.prototype.getShowHostListByConfig = function()
	{
		var re = this._isHiddenServerByConf();
		if (re === true)
			re = '';
		return re;
	}
	/**
	 * 是否被域名隐藏（根据配置文件看是否隐藏） serverName 为空时返回列表
	 */
	appFun.prototype._isHiddenServerByConf = function(serverName)
	{
		if (!config.hostShowServers)
		{
			layer.msg('no hostShowServers');
			return true;
		}
		var url = window.location.href.toLowerCase();
		var isHidden = true;
		var confi = null; // 配置文件
		// 先寻找模块列表，以最先匹配为准
		var urli = '';
		if (!this._isHiddenServerByConf.urli)
		{
			this._isHiddenServerByConf.urli = true;
			for ( var urlis in config.hostShowServers)
			{
				var au = urlis.split(',');
				for (var i = 0; i < au.length; i++)
				{
					if (url.indexOf(au[i].toLowerCase()) >= 0)
					{
						urli = urlis;
						this._isHiddenServerByConf.urli = urli;
						break;
					}
				}
				if (urli)
					break;
			}
		}
		urli = this._isHiddenServerByConf.urli;
		if (urli === true)
		{
			layer.msg('not find hostList');
			return true;
		}
		var confi = config.hostShowServers[urli].config;
		if (confi)
		{
			for ( var k in confi)
			{
				if (k == 'justSinglePage')
					this.isSinglePage(true);
				else
					config[k] = confi[k];
			}
		}
		var hostList = config.hostShowServers[urli].host;
		if (hostList && (hostList == '*' || (',' + hostList + ',').indexOf(',' + serverName + ',') >= 0))
			isHidden = false;
		else
			isHidden = true;
		if (!serverName)
			return hostList;
		return isHidden;
	}
	/**
	 * 取得微服务URL
	 */
	appFun.prototype.getServerUrl = function(serverName)
	{
		if (config.serversListConfig[serverName])
			return config.serversListConfig[serverName]['url'];
		else
			return '';
	}
	/**
	 * 取得设置全局变量
	 */
	appFun.prototype.g = function(k, v)
	{
		if (!appFun.prototype.globals)
			appFun.prototype.globals = {};
		if (arguments.length == 1)
			return appFun.prototype.globals[k];
		else if (arguments.length >= 2)
			appFun.prototype.globals[k] = v;
	}
	appFun.prototype.exed = function(k)
	{
		if (this.g('one_' + k))
			return true;
		this.g('one_' + k, true);
		return false;
	}
	/**
	 * 输出错误提示，只在调试错误时输出
	 */
	appFun.prototype.err = function(msg)
	{
		if (config.debug)
			errorMsg(msg);
		return null;
	}
	/**
	 * 设置语言
	 */
	appFun.prototype.setLang = function(lan, fun)
	{
		this.lan = new langFun(lan, fun);
	}
	appFun.prototype.addLang = function(serverName, arr)
	{
		this.lan.data[serverName] = arr;
	}
	appFun.prototype.getLanWord = function(wd)
	{
		return this.lan.getWord(wd);
	}
	/**
	 * 多语言翻译
	 */
	appFun.prototype.w = function(wd)
	{
		if (!this.lan)
			return wd;
		if (!wd)
			return '';
		var a = wd.split('.');
		var fy = (a.length == 3 && a[1] == 'fy');
		if (wd.length > 255 && !fy)
			wd = wd.substring(0, 255);
		// 不翻译单个单词
		if (fy && wd.indexOf(' ') < 0 && wd.indexOf('(') < 0)
		{
			// 转换为单词翻译
			return this.lan.w(a[0] + '.f.' + a[2]);
		}
		var ss = [];
		if (wd.indexOf('(') >= 0)
		{
			// 带参数了,需要把参数替换为“()”，然后按照顺序替换回来
			var ss = [];
			wd = wd.replace(/\([^\)]*\)/g, function(s)
			{
				if (s.length > 2)
					ss.push(s.substring(1, s.length - 1));
				else
					ss.push('');
				return '()';
			});
		}
		var word = this.lan.w(wd);
		// 替换括号中内容
		if (ss.length > 0 && typeof word == 'string')
		{
			var i = -1;
			word = word.replace(/（/g, '(');
			word = word.replace(/）/g, ')');
			word = word.replace(/\(\)/g, function(s)
			{
				i++;
				if (i < ss.length)
					return ' ( ' + ss[i] + ' ) ';
				else
					return s;
			});
			for (ii = i + 1; ii < ss.length; ii++)
			{
				// 替换结束后发现还有没有替换结束的，加在后面
				word += ' ( ' + ss[ii] + ' ) ';
			}
		}
		return word;
	}
	/**
	 * 翻译，除了括号外，所有的文本都需要翻译一下
	 */
	appFun.prototype.fw = function(wd, serverName)
	{
		wd = (wd + ' ').trim();
		if (!wd)
			return '';
		// 指定的不需要翻译的语句
		if (wd.indexOf('!') === 0)
			return wd.substring(1);
		// 如果语句过长，多半是错误提醒，直接返回原结果
		if (wd.length > 512)
			return wd;
		if (wd.indexOf(' ') < 0 && wd.indexOf('(') < 0)
		{
			return this.lan.w(serverName + '.f.' + wd);
		}
		// 保留方框
		wd = wd.replace(/\[\[/g, '(-leftk-)');
		wd = wd.replace(/\]\]/g, '(-rightk-)');
		wd = wd.replace(/[\[]/g, '(-');
		wd = wd.replace(/[\]]/g, '-)');
		var cc = ''; // 获取的段
		var re = ''; // 返回值
		var inc = 0; // 是否在括号里面
		var inh = 0; // 是否在HTML里面
		for (var i = 0; i <= wd.length; i++)
		{
			if (i >= wd.length)
				var c = '';
			else
				var c = wd.substring(i, i + 1);
			// 检验是否在括号里面
			if (c == '(' || c == ')' || (c == '' && inc > 0))
			{
				if (c == '')
					inc = 0;
				else
					inc += (c == '(' ? 1 : -1);
				cc += c;
				continue;
			}
			if (inc > 0)
			{
				cc += c;
				continue;
			}
			// 检验是否在HTML里面
			if (c == '<' && inh == 0)
			{
				cc = cc.replace(/\s+/g, ' ').trim();
				if (cc != '')
				{
					if (cc.indexOf(' ') < 0)
						re += cc;
					else
					{
						if (serverName == 'inner')
							re += cc;
						else
						{
							var sw = this._getFwServer(serverName, cc);
							serverName = sw[0];
							cc = sw[1];
							if (sw[2])
								re += cc;
							else
								re += this.w(serverName + '.fy.' + cc);
						}
					}
					cc = '';
				}
				cc += '<';
				inh = 1;
				continue;
			}
			else if (c == '>' || (c == '' && inh > 0))
			{
				cc += '>';
				inh = 0;
				re += cc;
				cc = '';
				continue;
			}
			if (inh > 0)
			{
				cc += c;
				continue;
			}
			// 都不是就进入翻译
			if (('?;,:.\\/_=-').indexOf(c) >= 0 || c == '')
			{
				cc = cc.replace(/\s+/g, ' ').trim();
				if (cc != '')
				{
					if (cc.indexOf(' ') < 0)
						re += cc;
					else
					{
						if (serverName == 'inner')
							re += cc;
						else
						{
							var sw = this._getFwServer(serverName, cc);
							serverName = sw[0];
							cc = sw[1];
							if (sw[2])
								re += cc;
							else
								re += this.w(serverName + '.fy.' + cc);
						}
					}
					cc = '';
				}
				re += c;
			}
			else
			{
				cc += c;
			}
		}
		if (cc != '')
		{
			cc = cc.replace(/\s+/g, ' ').trim();
			re += cc;
		}
		re = re.replace(/\(\-\![a-z]{1,16}\-\)/g, '');
		// 去掉服务器名称
		re = re.replace(/\(\-\![a-z]{1,16}\-\)/g, '');
		// 还原 [[ 或 ]]
		re = re.replace(/\([\s]{0,2}\-leftk\-[\s]{0,2}\)[\s]{0,1}/g, '[');
		re = re.replace(/\([\s]{0,2}\-rightk\-[\s]{0,2}\)[\s]{0,1}/g, ']');
		// 去掉中括号界符
		re = re.replace(/\([\s]{0,2}\-/g, ' ');
		re = re.replace(/\-[\s]{0,2}\)/g, ' ');
		re = re.replace(/\([\s]{0,10}wtp\./g, '<p>(wtp.').trim();
		// 去掉首部界符
		re = re.replace(/^[\?\;\,\:\.\\\/\_\=\-]/, '');
		return ' ' + re + ' ';
	}
	appFun.prototype._getFwServer = function(serverName, wd)
	{
		if (!serverName)
			serverName = 'login';
		if (wd.indexOf('!') === 0)
		{
			return [ serverName, wd.substring(1), true ];
		}
		var i = wd.indexOf('(-!');
		if (i >= 0)
		{
			var i2 = wd.indexOf('-)', i);
			if (i2 > i + 3 && i2 - i - 3 <= 16)
			{
				serverName = wd.substring(i + 3, i2);
				if (i === 0)
					wd = wd.substring(i2 + 2);
				else
					wd = wd.substring(0, i) + ' ' + wd.substring(i2 + 2);
				var se = configPara.val('servers', serverName, 'langservername');
				if (se)
					serverName = se;
			}
		}
		return [ serverName, wd ];
	}
	/**
	 * 取得hash
	 */
	appFun.prototype.hash = function(hash)
	{
		if (hash === undefined)
		{
			var hash = window.location.hash;
			if (hash && hash.indexOf('#_') === 0)
			{
				hash = hash.substring(2);
				if (hash)
				{
					var i = hash.indexOf('#');
					if (i > 0)
						return hash.substring(0, i);
					else if (i < 0)
						return hash;
				}
			}
			return '';
		}
		else
		{
			this.hash.changeTime = new Date().getTime();
			window.location.hash = '_' + hash;
			return hash;
		}
	}
	// 设置首页
	appFun.prototype.setHome = function(logintype, byhand, mustShow)
	{
		var that = this;
		if (!left.okToChangeMain())
		{
			left.okToChangeMain(function()
			{
				that.setHome(logintype, byhand, mustShow);
			});
			return;
		}
		if (!mustShow && login.isLoginByWxid())
			return;
		if (login.isLogin() && logintype == 'about')
		{
			left.face(false, 'about', true);
			return;
		}
		if (!login.isLogin())
		{
			left.face(false, logintype, logintype ? true : false);
		}
		else
		{
			left.face(true);
			left.showNavBar();
			left.showTreeToMain();
			this.bodyMax();
			if (byhand)
				this.hash('');
		}
	}
	/**
	 * 执行登录
	 */
	appFun.prototype.doLogin = function(backfun, tryIsLogin)
	{
		if (this.isInit)
			return;
		if (this._isLoginDoing || ($('body>.wrapper').is(':hidden')))
		{
			return;
		}
		if (tryIsLogin && login.isLogin())
		{
			backfun();
			return;
		}
		this._isLoginDoing = true;
		var that = this;
		var layerIndex = null;
		var form = new formFun({
			showmemo : false,
			method : 'wtp.login.user.login',
			submitOtherBtn : {
				k : {
					caption : this.w('cancel'),
					fun : function()
					{
						layer.close(layerIndex);
					},
				}
			},
			preDealDataFun : function(data)
			{
				var name = data['name'];
				var password = left.inputPassword($('#' + form.id + ' #password')[0], true);
				loginUser.login(name, password, function()
				{
					layer.close(layerIndex);
					loginUser.loginUserList(name);
					if (backfun)
						backfun();
					else
						loginUser.afterLogin();
				});
				return null;
			},
			paras : {
				bid : {
					inputtype : 'hidden',
					value : this.getBusinessId(),
				},
				name : {
					caption : this.w('userName'),
					required : true,
					value : this.getUserName(),
				},
				password : {
					inputtype : 'password',
					caption : this.w('Password'),
					required : true,
					enterfun : function()
					{
						form.submit();
					},
				}
			}
		});
		form.html += '<div class="dologin-wx">' + left.getWeiXinLoginHtml('login', 'wx_login_box_c', function()
		{
			layer.close(layerIndex);
			if (backfun)
				backfun();
		}) + '</div> &nbsp; <a class="wx_login_box-a" onclick="$(this).hide();$(\'.dologin-wx .wx_login_box\').show()"><i class="fa fa-weixin"> ' + app.w('wxlogin') + '</i></a>';
		layerIndex = showForm(this.w('userLogin'), form, null, Math.min($(window).width(), 600), 250, function()
		{
			that._isLoginDoing = false;
		}, 'abstop');
		setTimeout(function()
		{
			$('#' + form.id + ' #password').val('');
			$('#' + form.id + ' #password').on("input", function()
			{
				left.inputPassword(this);
			});
			$('#' + form.id + ' #password').on("propertychange", function()
			{
				left.inputPassword(this);
			});
		}, 1000);
		if (window.toAndroidApp)
		{
			var setIntervalIndex = 0;
			setIntervalIndex = setInterval(function()
			{
				if (login.isLogin() || !window.toAndroidApp.tryGetFinger || ($('.loginUser-doLogin').length <= 0))
				{
					clearInterval(setIntervalIndex);
					if (login.isLogin() && backfun)
						backfun();
					return;
				}
				window.toAndroidApp.tryGetFinger();
			}, 1000);
		}
	}
	/**
	 * 设备加密码
	 */
	appFun.prototype.driverKey = function(driverKey)
	{
		var name = 'driverKey';
		if (driverKey !== undefined)
		{
			this.setStorage(name, driverKey);
			return driverKey;
		}
		else
		{
			// 有效期10年
			return this.getStorage(name, false, 1000 * 3600 * 24 * 365 * 10);
		}
	}
	// /////////////////////////////////////////////////////
	// 本地存储
	/**
	 * 读取存储，当mustReadStorage为真时，必须从存储中获取
	 */
	appFun.prototype.getStorage = function(name, mustReadStorage, timeoutMs)
	{
		// 仅仅存储于浏览器的变量，即只有不存在时才读取存储 ，主要是登录信息和当前商家信息
		var justInWebKet = (',tokenendtime,token,username,userauth,business,serverName0,').toUpperCase();
		if (justInWebKet.indexOf(',' + name.toUpperCase().trim() + ',') >= 0)
			mustReadStorage = false;
		if (this.fixedStorageKeyValue[name] !== undefined)
			return this.fixedStorageKeyValue[name];
		if (!mustReadStorage && this.storage[name] !== undefined)
		{
			return this.storage[name];
		}
		var re = null;
		try
		{
			var re = JSON.parse(localStorage.getItem(name));
		}
		catch (err)
		{
			re = '';
		}
		if (re === null)
			re = '';
		if (typeof re == 'object' && re._t && re._t > 0)
		{
			var defaultTimeoutMs = 1000 * 3600 * 24 * 31; // 默认缓存时间（一个月）
			if (!(timeoutMs > 0))
				timeoutMs = defaultTimeoutMs;
			if (re._t < new Date().getTime() - timeoutMs)
			{
				this.setStorage(name, '');
				re = '';
			}
			else
			{
				if (re._t < new Date().getTime() - timeoutMs / 10)
				{
					// 时间过了十分之一，要刷新时间
					this.setStorage(name, re._d);
				}
				re = re._d;
			}
		}
		else if (re !== '')
		{
			this.setStorage(name, '');
			re = '';
		}
		this.storage[name] = re;
		return re;
	}
	appFun.prototype.setStorage = function(name, val)
	{
		if (this.fixedStorageKeyValue[name] !== undefined)
			return;
		if (val === '' || val === null)
			localStorage.removeItem(name);
		else
		{
			localStorage.setItem(name, JSON.stringify({
				_t : new Date().getTime(),
				_d : val
			}));
		}
		this.storage[name] = val;
		if (Math.random() < 0.001)
		{
			// 千分之一机会
			this.clearStorage(true);
		}
	}
	/**
	 * 清除设置，一年以上的无条件清除
	 */
	appFun.prototype.clearStorage = function(justClearTimeout)
	{
		for (var i = localStorage.length - 1; i >= 0; i--)
		{
			var k = localStorage.key(i);
			if (justClearTimeout)
				this.getStorage(k, true, 1000 * 3600 * 24 * 365);
			else
				localStorage.removeItem(k);
		}
		this.storage = {};
	}
	// 本地存储结束
	appFun.prototype.isIphone = function(need)
	{
		var userAgent = window.navigator ? navigator.userAgent.toLowerCase() : '';
		if (userAgent && /safari/.test(navigator.userAgent) && !/chrome/.test(navigator.userAgent))
		{
			return true;
		}
		var appVersion = window.navigator ? navigator.appVersion.toLowerCase() : '';
		if (appVersion && (appVersion.indexOf('ipad') > -1 || appVersion.indexOf('iphone') > -1))
			return true;
		return false;
	}
	/*
	 * 是否需要软键盘
	 */
	appFun.prototype.needWTPJp = function(need)
	{
		if (this.isBoard)
			return true;
		if (!this.vm)
			return false;
		if (need === true || need === false)
		{
			if (need && this.isIphone())
			{
				layer.msg('can not use wtp JP in iphone');
				return;
			}
			this.needWTPJp.v = need;
			$('input').each(function()
			{
				if ($(this).attr('editabled'))
				{
					this.readOnly = need;
					if (need)
						$(this).addClass('editabled');
					else
						$(this).removeClass('editabled');
				}
			});
		}
		if (this.needWTPJp.v === true || this.needWTPJp.v === false)
			return this.needWTPJp.v;
		this.needWTPJp.v = ((this.vm || window.toAndroidApp) && config.needWTPJp) && !this.isIphone();
		return this.needWTPJp.v;
	}
	appFun.prototype.getUserName = function()
	{
		return this.getStorage('username');
	}
	appFun.prototype.getWtpCaption = function()
	{
		if (config.wtpCaption && config.wtpCaption[this.getLangName()])
			return config.wtpCaption[this.getLangName()];
		else
		{
			return this.w('systemcaption');
		}
	}
	appFun.prototype.hideTableOption = function(isSetm)
	{
		if (arguments.length <= 0)
		{
			// 读取
			if (this.hideTableOption.value === true || this.hideTableOption.value === false)
				return this.hideTableOption.value;
			return !!this.vm;
		}
		var m = !!isSetm;
		this.hideTableOption.value = m;
		left.rightTopMenu();
		if (m)
		{
			$('.tablebox .thop').addClass('hideop');
			$('.tablebox .tdop').addClass('hideop');
		}
		else
		{
			$('.tablebox .thop').removeClass('hideop');
			$('.tablebox .tdop').removeClass('hideop');
		}
		return m;
	}
	appFun.prototype.bodyMax = function(isSetm, just)
	{
		this.setAppSize();
		var mi = (this.getStorage('bodyMax') != 'no' && !this.vm);
		if (arguments.length > 0)
		{
			if (isSetm === true || isSetm === false)
				mi = isSetm;
			else
				mi = !mi;
			closeFullLayer();
			this.setStorage('bodyMax', mi ? 'yes' : 'no');
			left.rightTopMenu();
		}
		if (mi)
			$('body').removeClass('minbody');
		else
			$('body').addClass('minbody');
		return mi;
	}
	/**
	 * 取得主操作框高度
	 */
	appFun.prototype.getMainHeight = function()
	{
		var h = getWindowHeight() - (this.vm ? 0 : 70) - 42;
		if (left.isTopHeadNav())
			h += 45;
		if (left.hideTop())
			h += 40;
		return h;
	}
	/**
	 * 设置当前商家
	 */
	appFun.prototype.setBusiness = function(id, backfun)
	{
		if (!login.isLogin())
			return;
		if (!id)
		{
			this.business(null);
			if (backfun)
				backfun(id, '', false, false);
			return;
		}
		if (this._setBusinessIngId === id)
			return;
		this._setBusinessIngId = id;
		var that = this;
		// 进度
		var oldBusinessId = that._business.id;
		this._business.id = id;
		this.init.bid = -1;
		ajax.request('wtp.login.user.setBusiness', {
			id : id,
			testBusinessSingle : this._businessSingle === null ? 'yes' : 'no'
		}, function(d, ad)
		{
			that._setBusinessIngId = 0;
			that.business({
				id : ad['businessId'],
				name : ad['businessName']
			});
			if (ad['businessSingle'] != undefined)
				that._businessSingle = ad['businessSingle'] == 'yes';
			// 取得微服务地址
			that._setServersConfig(ad['servers']);
			that.loadServer(function()
			{
				if (backfun)
					backfun(that._business.id, that._business.name);
				if (oldBusinessId != that._business.id)
				{
					loginUser.goToPage();
				}
			});
		}, function(msg, msg2)
		{
			that._setBusinessIngId = 0;
			layer.msg(msg2);
			that.business(null);
			if (backfun)
				backfun(0, '', false, false);
			left.showBottom(true);
		});
	}
	appFun.prototype.showBusinessInfo = function(bid)
	{
		if (!bid)
			return;
		ajax.request('wtp.login.business.list', {
			id : bid
		}, function(d, ad)
		{
			if (d.length == 0)
				errorMsg('not find business');
			else
			{
				var s = '';
				s += '<p>Id : ' + d[0].id;
				s += '<p>Name : ' + d[0].name;
				s += '<p>LinkMan : ' + d[0].linkMan;
				s += '<p>Tel : ' + d[0].tel;
				s += '<p>Created : ' + getDateStr(d[0].created, false, false, true);
				showMsg(s);
			}
		});
	}
	/**
	 * 取得当前商家名称
	 */
	appFun.prototype.getBusinessName = function(isSimple, name, reEmptyIfNone)
	{
		if (!name)
		{
			if (!this._business.id || this._business.id <= 0)
			{
				if (reEmptyIfNone)
					return '';
				else
				{
					return this.w('selectBusiness');
				}
			}
			if (!this._business.name)
				return (this._business.id + ' ').trim();
			name = this._business.name;
		}
		if (isSimple)
		{
			name = name.replace('（', '(');
			var i = name.indexOf('(');
			if (i <= 0)
				i = 32;
			name = name.substring(0, i);
		}
		return name;
	}
	/**
	 * 是不是单商家
	 */
	appFun.prototype.isSingleBusiness = function()
	{
		return this._businessSingle;
	}
	/**
	 * 当前商家号
	 */
	appFun.prototype.getBusinessId = function()
	{
		if (!this._business.id || this._business.id <= 0)
			return 0;
		return this._business.id;
	}
	/**
	 * 选择商家,d0表示已经查询到的数据，d0为false表示当前条件下没有数据
	 */
	appFun.prototype.selectBusiness = function(backfun, must, notset, d0, page, mulSelect, initValues, isInitPage)
	{
		var that = this;
		var paddingtb = 150;
		if (!page || page < 1)
			page = 1;
		var tdHeight = (new tableFun()).getTdHeight();
		var pagesize = Math.floor(($(window).height() - paddingtb) / tdHeight);
		if (mulSelect)
			pagesize = 200;
		if (!must && this._business.id > 0 && !isInitPage)
		{
			if (this._business.id != login.getBusinessId())
			{
				// 清空当前商家信息
				this.setBusiness();
			}
			else
			{
				if (backfun)
				{
					backfun(this._business.id, this._business.name);
				}
				return;
			}
		}
		if (page <= 1 && !d0 && d0 !== false && !mulSelect)
		{
			// 初次探寻，看是不是只有一个
			var para = {
				page : page,
				pagesize : pagesize,
				byWebUILoginSelect : notset ? 'no' : 'yes',
				initBusinessId : that._business.id,
				topBusinessId : must && notset ? that._business.id : 0,
			};
			ajax.request('wtp.login.business.list', para, function(d, ad)
			{
				that._businessSingle = (d.length == 1);
				if (d.length > 0 && page == 1 && ((d.length == 1 && !must && that._business.id <= 0) || isInitPage))
				{
					var bi = 0;
					if (isInitPage && that._business.id > 0)
					{
						for (var i = 0; i < d.length; i++)
						{
							if (d[i].id == that._business.id)
							{
								bi = i;
								break;
							}
						}
					}
					// 只有一个符合条件的商家就直接返回
					if (!notset)
					{
						that.setBusiness(d[bi].id, function(id, name)
						{
							if (backfun)
								backfun(id, name);
						});
					}
					else
					{
						if (backfun)
							backfun(d[bi].id, d[bi].name);
					}
					return;
				}
				if (d.length <= 0)
				{
					if (isInitPage)
					{
						that.business(null);
						if (backfun)
							backfun(0, '');
						return;
					}
					d = false;
					that.setBusiness(0);
				}
				that.selectBusiness(backfun, must, notset, d, page, mulSelect, initValues, false);
			});
			return;
		}
		if (!left.okToChangeMain())
		{
			left.okToChangeMain(function()
			{
				that.selectBusiness(backfun, must, notset, d0, page, mulSelect, initValues, isInitPage);
			});
			return;
		}
		var table = new tableFun({
			container : '',
			showheader : false,
			showpage : true,
			classname : 'tablelist',
			tophtml : {
				search : {
					issearch : true,
					caption : ' ',
					icon : 'fa-search',
					placeholder : that.w('searchNameOrId'),
					fun : function(w)
					{
						w = (w + ' ').trim();
						if (/^[0-9]*$/.test(w))
						{
							table.setSearchPara({
								id : parseInt(w)
							});
						}
						else
						{
							table.setSearchPara({
								name : w
							});
						}
						table.setData(null, 1);
					}
				},
				cmd2 : {
					caption : that.w('clear'),
					icon : 'fa-eraser',
					fun : function()
					{
						layer.close(that.selectBusiness.layerIndex);
						if (!notset)
						{
							that.setBusiness(0, function()
							{
								if (backfun)
									backfun(0, '');
							});
						}
						else
						{
							if (backfun)
								backfun(0, '');
						}
					}
				},
			},
			clickTrFun : function(index, idi, data)
			{
				var name = data['name'];
				if (!notset)
				{
					that.setBusiness(idi, function(id, name)
					{
						if (backfun)
							backfun(id, name);
					});
				}
				else
				{
					if (backfun)
						backfun(idi, name);
				}
				layer.close(that.selectBusiness.layerIndex);
			},
			loadDataFun : function(page, fun, searchpara)
			{
				if (d0 || d0 === false)
				{
					d0 = rename(d0);
					fun(d0, d0.length >= pagesize ? (page + 1) : page);
					d0 = null;
				}
				else
				{
					var para = {
						page : page,
						pagesize : pagesize,
						byWebUILoginSelect : notset ? 'no' : 'yes'
					};
					var isSearch = false;
					if (searchpara)
					{
						for ( var na in searchpara)
						{
							var s = searchpara[na];
							if (s > 0 && s == parseInt(s))
								na = 'id';
							para[na] = s;
							isSearch = true;
						}
					}
					ajax.request('wtp.login.business.list', para, function(d, ad)
					{
						if (!isSearch)
							that._businessSingle = (d.length == 1);
						d = rename(d);
						fun(d, d.length >= pagesize ? (page + 1) : page);
						if (mulSelect && initValues)
						{
							if (typeof initValues == 'object')
								initValues = initValues.join(',');
							setTimeout(function()
							{
								initValues = ',' + initValues + ',';
								for (var i = 0; i < d.length; i++)
								{
									var id = $('#' + table.id + ' tr.i' + i + ' td.td-id span').html();
									if (initValues.indexOf(',' + id + ',') >= 0)
									{
										var ss = $('#' + table.id + ' tr.i' + i + ' td.thtdmu input');
										if (ss.length > 0)
											ss[0].checked = true;
									}
								}
							}, 100);
						}
					});
				}
			},
			'header' : {
				_mu_ : mulSelect,
				'id' : [ 'id', '1%' ],
				'name' : '',
				'names' : that.w('name'),
				_op_ : !mulSelect ? null : [ {
					_mu_ : true,
					title : this.w('select'),
					icon : 'fa-check-square',
					hideop : true,
					muonce : true,
					fun : function(index, idi, data)
					{
						if (backfun)
							backfun(idi, data['name']);
						layer.close(that.selectBusiness.layerIndex);
					}
				} ]
			}
		});
		if (this.selectBusiness.layerIndex)
		{
			layer.close(this.selectBusiness.layerIndex);
		}
		if (this.vm)
		{
			this.selectBusiness.layerIndex = showFullLayer(that.w('selectBusiness'), table.html);
		}
		else
		{
			this.selectBusiness.layerIndex = showList(that.w('selectBusiness'), table.html, [ '400px', $(window).height() + 'px' ]);
		}
		// 整理名称
		function rename(d0)
		{
			if (!d0)
				d0 = [];
			for (var i = 0; i < d0.length; i++)
			{
				d0[i]['names'] = d0[i]['name'];
				if (d0[i].id == that._business.id)
					d0[i]['names'] = '<b>' + d0[i]['names'] + '</b>';
			}
			return d0;
		}
	}
	/**
	 * 右键菜单
	 */
	appFun.prototype.rightMenu = function(x, y, w, data, backfun, classname, fixedHeight)
	{
		if (this.rightMenuLayerIndex)
		{
			layer.close(this.rightMenuLayerIndex);
			this.rightMenuLayerIndex = 0;
		}
		if (arguments.length == 0)
			return;
		x -= 24;
		y += 20;
		if (!w || w <= 0)
			w = 200;
		var h = 24;
		if (!classname)
			classname = '';
		var hh = $(window).height();
		var t = '<ul class="rightmenu apprightmenu ' + classname + '">';
		for ( var k in data)
		{
			if (!data[k])
				continue;
			if (typeof data[k] == 'object')
			{
				var title = data[k]['title'] || data[k]['caption'];
				var cla = data[k]['justHtml'] ? 'html' : '';
				if (title)
					t += '<li class="' + cla + '" key="' + k + '" >' + (data[k]['icon'] ? '<i style="width:14px" class="fa ' + data[k]['icon'] + '"></i> ' : '') + title + '</li>';
			}
			else if (data[k].indexOf('<li') >= 0)
				t += data[k];
			else
				t += '<li key="' + k + '" >' + data[k] + '</li>';
			h += hh > 600 ? 28 : 24; // 单行高度
		}
		t += '</ul>';
		x -= $(document).scrollLeft();
		y -= $(document).scrollTop();
		if (x + w > $(window).width())
			x = $(window).width() - w;
		if (y + h > $(window).height())
			y = $(window).height() - h;
		else if (x < 0)
			x = 0;
		if (y < 0)
			y = 0;
		if (!backfun)
		{
			backfun = function(k)
			{
				if (data[k] && data[k]['fun'])
					data[k]['fun']();
			};
		}
		this.rightMenuBackfun = backfun;
		this.rightMenuLayerIndex = layer.open({
			type : 1,
			title : false,
			offset : [ y, x ],
			shadeClose : true,
			shade : 0.1,
			area : [ w + 'px', (fixedHeight > 0 ? fixedHeight : h) + 'px' ],
			content : t,
			closeBtn : 0,
			zIndex : fullLayer_max_zindex2,
			skin : 'rightmenu ' + (classname || ''),
		});
	}
	/**
	 * 设置微服务的配置
	 */
	appFun.prototype._setServersConfig = function(servers)
	{
		if (!servers)
			return;
		// 备份与还原
		if (!config.serversListConfig0)
			config.serversListConfig0 = JSON.stringify(config.serversListConfig);
		else
			config.serversListConfig = JSON.parse(config.serversListConfig0);
		for ( var serverName in servers)
		{
			if (!config.serversListConfig[serverName])
				continue;
			var s = servers[serverName];
			var s0 = config.serversListConfig[serverName];
			for ( var k in s)
			{
				if (s && s[k])
					s0[k] = s[k];
			}
		}
	}
	// 取得画布
	appFun.prototype.getCanvas = function(divid, dx0width, dy0height, padding, onmouseevent, backfun)
	{
		loadJs(this.core + '/js/public/canvas.js', function()
		{
			var canvas = new canvasFun(divid, dx0width, dy0height, padding, onmouseevent);
			backfun(canvas);
		});
	}
	// 执行刷新命令
	appFun.prototype.refresh = function(id)
	{
		var find = false;
		$('.tablebox ._refresh').each(function()
		{
			if ($(this).parents('#maincontent').length > 0 || $(this).parents('.fulllayer').length > 0)
			{
				var ta = (new tableFun).getThis(this);
				if (ta)
				{
					find = true;
					ta.setData();
				}
			}
		});
		if (!find)
		{
			login.refreshToken(0, true);
			left.goPage(this.hash());
		}
	}
	appFun.prototype.setFixedStorageKeyValue = function(key, value)
	{
		if (typeof key == 'object')
		{
			for ( var k in key)
				this.fixedStorageKeyValue[k] = key[k];
		}
		else
			this.fixedStorageKeyValue[key] = value;
	}
	window.app = new appFun();
}());
